package org.zasadnyy.redlions.players.client.ds;

import java.util.List;

import org.zasadnyy.redlions.players.shared.model.PlayerItem;
import org.zasadnyy.redlions.players.shared.remote.PlayersCrudRemote;
import org.zasadnyy.redlions.players.shared.remote.PlayersCrudRemoteAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.types.DateDisplayFormat;
import com.smartgwt.client.types.FieldType;

public class PlayersDataSource extends GwtRpcDataSource {

	private PlayersCrudRemoteAsync service = GWT
			.create(PlayersCrudRemote.class);
	
	private ItemConverter converter = new ItemConverter();

	public PlayersDataSource() {

		DataSourceField id = new DataSourceField(PlayerItem.ID, FieldType.TEXT);
		id.setHidden(true);
		id.setPrimaryKey(true);
		addField(id);

		DataSourceField name = new DataSourceField(PlayerItem.NAME,
				FieldType.TEXT);
		name.setTitle("Ім'я");
		addField(name);

		DataSourceField surname = new DataSourceField(PlayerItem.SURNAME,
				FieldType.TEXT);
		surname.setTitle("Прізвище");
		addField(surname);

		DataSourceField photoUrl = new DataSourceField(PlayerItem.PHOTO_URL,
				FieldType.TEXT);
		photoUrl.setTitle("Посилання на картинку");
		addField(photoUrl);

		DataSourceField nativeCity = new DataSourceField(
				PlayerItem.NATIVE_CITY, FieldType.TEXT);
		nativeCity.setTitle("Рідне місто");
		addField(nativeCity);

		DataSourceField birthday = new DataSourceField(PlayerItem.BIRTHDAY,
				FieldType.DATE);
		birthday.setTitle("День народження");
		addField(birthday);

		DataSourceField playsFrom = new DataSourceField(PlayerItem.PLAYS_FROM,
				FieldType.DATE);
		playsFrom.setTitle("Грає з");
		playsFrom.setDisplayFormat(DateDisplayFormat.TOUSSHORTDATE);
		addField(playsFrom);

		DataSourceField tournaments = new DataSourceField(
				PlayerItem.TOURNAMENTS, FieldType.ANY);
		tournaments.setTitle("Відвідані турніри");
		addField(tournaments);
	}

	@Override
	protected void executeFetch(final String requestId,
			final DSRequest request, final DSResponse response) {

		Criteria criteria = request.getCriteria();
		if (criteria != null) {
			String id = criteria.getAttribute(PlayerItem.ID);
			if (id != null && id != "") {
				service.getPlayerById(id, new AsyncCallback<PlayerItem>() {

					@Override
					public void onSuccess(PlayerItem result) {
						PlayerRecord[] records = new PlayerRecord[1];
						records[0] = new PlayerRecord(result);
						response.setData(records);
						processResponse(requestId, response);
					}

					@Override
					public void onFailure(Throwable caught) {
						response.setStatus(RPCResponse.STATUS_FAILURE);
						processResponse(requestId, response);
					}
				});
			} else {
				service.getAllPlayers(new AsyncCallback<List<PlayerItem>>() {

					@Override
					public void onSuccess(List<PlayerItem> players) {
						PlayerRecord[] records = new PlayerRecord[players
								.size()];
						for (int i = 0; i < records.length; i++) {
							records[i] = new PlayerRecord(players.get(i));
						}
						response.setData(records);
						processResponse(requestId, response);
					}

					@Override
					public void onFailure(Throwable caught) {
						response.setStatus(RPCResponse.STATUS_FAILURE);
						processResponse(requestId, response);
					}
				});
			}
		}

	}

	@Override
	protected void executeAdd(final String requestId, DSRequest request,
			final DSResponse response) {
		PlayerItem playerItem = converter.recordToPlayerItem(request.getAttributeAsRecord("data"));
		service.addOrEditPlayer(playerItem, new DefaultAsyncCallback<Void>(
				requestId, response));
	}

	@Override
	protected void executeUpdate(String requestId, DSRequest request,
			DSResponse response) {
		PlayerItem playerItem = converter.recordToPlayerItem(request.getAttributeAsRecord("data"));
		service.addOrEditPlayer(playerItem, new DefaultAsyncCallback<Void>(
				requestId, response));
	}

	@Override
	protected void executeRemove(String requestId, DSRequest request,
			DSResponse response) {
		Record player = request.getAttributeAsRecord("data");		
		service.deletePlayerById(player.getAttribute(PlayerItem.ID), new DefaultAsyncCallback<Void>(requestId, response));
	}

	public class DefaultAsyncCallback<L> implements AsyncCallback<L> {

		private final String requestId;
		private final DSResponse response;

		public DefaultAsyncCallback(String requestId, DSResponse response) {
			this.requestId = requestId;
			this.response = response;
		}

		public void onFailure(Throwable throwable) {
			response.setStatus(DSResponse.STATUS_FAILURE);
		}

		public void onSuccess(L o) {
			response.setStatus(DSResponse.STATUS_SUCCESS);
			processResponse(requestId, response);
		}
	}

}
